package com.platform.modules.sms.util;

import cn.hutool.extra.spring.SpringUtil;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.config.DevConfig;
import com.platform.config.KaptchaConfig;
import com.platform.modules.sms.SmsSend;
import com.platform.modules.sms.auto.ISmsAutoBuild;
import com.platform.modules.sms.entitys.SmsTemplateEntity;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class SmsUtil {

    // todo risk 需要加上不同的短信标识
    public static void codeValidate(JedisUtil jedisUtil, String phone, String code){
        if(DevConfig.isDev && "8888".equals(code)){
            // 测试环境下用
            return;
        }
        String smsCode = jedisUtil.get(Constant.PRE_SMS + phone);
        if (StringUtils.isBlank(smsCode)) {
            throw new BusinessException("验证码已失效，请重新获取");
        }
        if (!code.equals(smsCode)) {
            errorCountValidate(jedisUtil,phone);
            throw new BusinessException("验证码错误");
        }
        // 验证通过后删除redis中的验证码
        jedisUtil.del(Constant.PRE_SMS + phone);
    }

    public static void errorCountValidate(JedisUtil jedisUtil, String phone){
        String cacheKey = Constant.PRE_SMS_ERROR_COUNT + phone;
        if(jedisUtil.incrBy(cacheKey,1) >= 10){
            jedisUtil.del(Constant.PRE_SMS + phone);
            throw new BusinessException("已达最大可尝试次数，请重新获取验证码！");
        }
    }

    /**
     * 校验图像验证码
     *
     * @param uuid
     * @param captcha
     * @return
     */
    public static void captchaValidate(JedisUtil jedisUtil, String uuid, String captcha) {
        // 图形验证码效验
        ValidUtils.allNotNull(uuid, captcha);
        boolean captchaResult = Optional.ofNullable(jedisUtil.get(KaptchaConfig.REDIS_KYE + uuid)).orElse("").equals(captcha);
        if (!captchaResult) {
            throw new BusinessException("验证码不正确");
        }
        jedisUtil.del(KaptchaConfig.REDIS_KYE + uuid);
    }

    public final static String symbol = "${%s}";
    public final static Pattern symbolPat = Pattern.compile("\\$\\{([a-zA-Z\\d]+)\\}");
    public final static Pattern symbolStr = Pattern.compile("[a-zA-Z\\d]+");
    private static Map<String, ISmsAutoBuild> autoBuildMap = null;

    public static void autoBuild(SmsTemplateEntity entity, SmsSend smsSend, Map<String, String> params) {
        initAutoBuildMap();
        Matcher matcher = symbolPat.matcher(entity.getContent());
        String flag;
        StringBuffer strBuffer = new StringBuffer();
        while (matcher.find()) {
            Matcher matcher2 = symbolStr.matcher(matcher.group());
            if (matcher2.find()) {
                ISmsAutoBuild autoBuild = autoBuildMap.get(flag = matcher2.group());
                matcher.appendReplacement(strBuffer,
                        autoBuild != null ? autoBuild.apply(entity, smsSend, params) :
                                params != null ? params.get(flag) : "");
            }
        }
        matcher.appendTail(strBuffer);
        smsSend.content = strBuffer.toString();
        smsSend.params = entity.getParams();
    }

    private static void initAutoBuildMap() {
        if (autoBuildMap == null) {
            synchronized (ObjectUtils.class) {
                if (autoBuildMap == null) {
                    autoBuildMap = SpringUtil.getBeansOfType(ISmsAutoBuild.class);
                    if (autoBuildMap == null) {
                        autoBuildMap = new HashMap<>();
                    }
                }
            }
        }
    }

}
